﻿/*
Plugin=CustomPlugin_SmartExtract
Name1=智能解压
Command1=CustomPlugin_SmartExtract
Version=1.0
*/


CustomPlugin_SmartExtractBandiZip(){          ;IntUnZip ======= intelligent UnZip


	CandySelected := QZData("Files")
	;~ candyselected=%1%

	;随机密码长度【10-16位之间】
	 if (StrPL=-1)
	 {
		Random ,StrPL,10,16
	 }


;务必修改成你的路径
	BandzipExePath=%A_ScriptDir%\Apps\BandiZip\Bandizip64.exe
	bzExePath=%A_ScriptDir%\Apps\BandiZip\bz.exe

	7z=%A_ScriptDir%\Apps\7-Zip\7z.exe
	7zg=%A_ScriptDir%\Apps\7-Zip\7zG.exe
;务必修改成你的路径

	IntUnZip_Many_In_FirstLevel:=0
	IntUnZip_Folder_In_FirstLevel:=0
	aaaa:=
	bbbb:=

	Splitpath ,CandySelected,,IntUnZip_FileDir,,IntUnZip_FileNameNoExt,IntUnZip_FileDrive
	IntUnZip_FileLists=%IntUnZip_FileDir%\IntUnZip_%a_now%.txt
	;~ MsgBox %CandySelected%___%IntUnZip_FileDir%__%IntUnZip_FileNameNoExt%
	DriveSpaceFree, IntUnZip_FreeSpace, %IntUnZip_FileDrive%
	FileGetSize, IntUnZip_FileSize, %CandySelected%, M
	If ( IntUnZip_FileSize > IntUnZip_FreeSpace )
	{
		MsgBox 磁盘空间不足,请检查后再解压。`n------------`n压缩包大小为%IntUnZip_FileSize%M`n剩余空间为%IntUnZip_FreeSpace%M
		Return
	}

	FilePath:=QZData("Files")

	; if (StrPL=0)
	; 	CmdBook := "bc -l:" . StrL . " -r -y -aoa" . " -v:" . StrV . " -fmt:" . Strfmt . " " . FilePath	;取消加密压缩功能
	; else
	; {

	StrPL:=-1,
	StrPa:="Wwd"
	Strfmt:="7z"
	StrV:="4GB"
	StrL:=9
	toTxt:=0

		;随机密码生成
		RandomStr := RandomPass(StrPa,StrPL)
		; CmdBook := "bc -l:" . StrL . " -r -aoa  -y -p:" . RandomStr . " -v:" . StrV . " -fmt:" . Strfmt . " -cmt:解压密码(" . StrPL . "字符)：" . RandomStr . " " . FilePath
		CmdBook := "bc -l:" . StrL . " -r -y -aoa" . " -v:" . StrV . " -fmt:" . Strfmt . " " . FilePath	;取消加密压缩功能
		clipboard = 
		clipboard := "解压密码：" . RandomStr
	; }

	 if(toTxt=1){
	 
			FileAppend ,%clipboard%,%A_Desktop%\SecData.txt
			FileAppend ,`t,%A_Desktop%\SecData.txt
			FileAppend ,%RandomStr%,%A_Desktop%\SecData.txt
			FileAppend ,`r`n,%A_Desktop%\SecData.txt
	 }
	BandizipCMD:= BandzipExePath . " " . CmdBook
	StdOutToVar(BandizipCMD)
	return
	
	Runwait, %Comspec% /C %7Z% L "%CandySelected%" `>"%IntUnZip_FileLists%",,hide

	;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
	Loop,read,%IntUnZip_FileLists%
	{
		FileLineStr:=a_loopreadline
		If(regexmatch(FileLineStr,"^(\d\d\d\d-\d\d-\d\d)"))
		{
			If (Instr(FileLineStr,"D")=21)  ;本行如果包含\或者有d标志，则判定为文件夹 Or Instr(a_loopreadline,"\")
			{
				IntUnZip_Folder_In_FirstLevel=1
			}
			if (substr(FileLineStr,21,1)!=" ")
			{
				aaaa:=RegExReplace(FileLineStr,"^\d{4}-\d{2}-\d{2}.{43}(.*?)(\\.*|$)","$1")
				If(bbbb != aaaa  And  bbbb!="" )
				{
					IntUnZip_Many_In_FirstLevel=1
					break
				}
				bbbb:=aaaa
			}
		}
	}
	Filedelete,%IntUnZip_FileLists%
	;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
	If(IntUnZip_Many_In_FirstLevel=0 && IntUnZip_Folder_In_FirstLevel=0 )   ;压缩文件内，首层有且仅有一个文件
	{
		Run, %7Zg% X "%CandySelected%" -O"%IntUnZip_FileDir%"    ;覆盖还是改名，交给7z
	}
	Else If(IntUnZip_Many_In_FirstLevel=0 && IntUnZip_Folder_In_FirstLevel=1 )   ;压缩文件内，首层有且仅有一个文件夹
	{
		Ifexist,%IntUnZip_FileDir%\%aaaa%   ;已经存在了以“首层文件夹命名”的文件夹，怎么办？
		{
			Loop
			{
				IntUnZip_newfoldername=%IntUnZip_FileDir%\%aaaa%( %A_index% )
				If !Fileexist( IntUnZip_newfoldername )
				{
					Run, %7Zg% X "%CandySelected%" -O"%IntUnZip_newfoldername%"
					Break
				}
			}
		}
		Else  ;没有“首层文件夹命名”的文件夹，那就太好了
		{
			Run, %7Zg% X "%CandySelected%" -O"%IntUnZip_FileDir%"
			;~ Sleep 3500	
			;~ FileMove, %IntUnZip_FileDir%\%IntUnZip_FileNameNoExt%, %IntUnZip_FileDir%
			;~ ToolTip
			return
		}
	}
	Else  ;压缩文件内，首层有多个文件夹
	{
		Ifexist %IntUnZip_FileDir%\%IntUnZip_FileNameNoExt%  ;已经存在了以“IntUnZip_FileNameNoExt”的文件夹，怎么办？
		{
			Loop
			{
				IntUnZip_newfoldername=%IntUnZip_FileDir%\%IntUnZip_FileNameNoExt%( %A_index% )
				If !Fileexist( IntUnZip_newfoldername )
				{
					Run, %7Zg% X "%CandySelected%"   -O"%IntUnZip_newfoldername%"
					Break
				}
			}
		}
		Else ;没有，那就太好了
		{
			IntUnZip_FileNameNoExt=%IntUnZip_FileNameNoExt%
			Run, %7Zg% X  "%CandySelected%" -O"%IntUnZip_FileDir%\%IntUnZip_FileNameNoExt%"
		}
	}
	Return
}



;=====================================================================o
;                           河大密码生成函数                         ;|
;---------------------------------------------------------------------o

RandomPass(kind:="Wwd",length:=8){
;类型 W大写 w小写 d数字 可以组合
char := [1,2,3,4,5,6,7,8,9,"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",0,1,2,3,4,5,6,7,8,9]
char[0] := 0 ;定义数组
option := kind
kind = 0 ;必须先赋值  不然后面的加法无效
kind := InStr(option,"W",1) ? kind+100 : kind ;InStr区分大小写
kind := InStr(option,"w",1) ? kind+10 : kind
kind := InStr(option,"d") ? kind+1 : kind
if kind=111
	min:=0,max:=61
else if kind=110
	min:=10,max:=61
else if kind=11
	min:=0,max:=35
else if kind=101
	min:=36,max:=71
else if kind=1
	min:=0,max=9
else if kind=10
	min:=10,max=35
else if kind=100
	min:=36,max=61
loop % length
{
Random, l, %min%, %max%
str .= char[l]
}
return str
}

;=====================================================================o
;				runanyctrl huizz 大佬                         		 ;|
;				后台运行cmd并读取cmd输出结果                         ;|
;---------------------------------------------------------------------o
StdOutToVar(cmd) {
	DllCall("CreatePipe", "PtrP", hReadPipe, "PtrP", hWritePipe, "Ptr", 0, "UInt", 0)
	DllCall("SetHandleInformation", "Ptr", hWritePipe, "UInt", 1, "UInt", 1)

	VarSetCapacity(PROCESS_INFORMATION, (A_PtrSize == 4 ? 16 : 24), 0)    ; http://goo.gl/dymEhJ
	cbSize := VarSetCapacity(STARTUPINFO, (A_PtrSize == 4 ? 68 : 104), 0) ; http://goo.gl/QiHqq9
	NumPut(cbSize, STARTUPINFO, 0, "UInt")                                ; cbSize
	NumPut(0x100, STARTUPINFO, (A_PtrSize == 4 ? 44 : 60), "UInt")        ; dwFlags
	NumPut(hWritePipe, STARTUPINFO, (A_PtrSize == 4 ? 60 : 88), "Ptr")    ; hStdOutput
	NumPut(hWritePipe, STARTUPINFO, (A_PtrSize == 4 ? 64 : 96), "Ptr")    ; hStdError
	
	if !DllCall(
	(Join Q C
		"CreateProcess",             ; http://goo.gl/9y0gw
		"Ptr",  0,                   ; lpApplicationName
		"Ptr",  &cmd,                ; lpCommandLine
		"Ptr",  0,                   ; lpProcessAttributes
		"Ptr",  0,                   ; lpThreadAttributes
		"UInt", true,                ; bInheritHandles
		"UInt", 0x08000000,          ; dwCreationFlags
		"Ptr",  0,                   ; lpEnvironment
		"Ptr",  0,                   ; lpCurrentDirectory
		"Ptr",  &STARTUPINFO,        ; lpStartupInfo
		"Ptr",  &PROCESS_INFORMATION ; lpProcessInformation
	)) {
		DllCall("CloseHandle", "Ptr", hWritePipe)
		DllCall("CloseHandle", "Ptr", hReadPipe)
		return ""
	}

	DllCall("CloseHandle", "Ptr", hWritePipe)
	VarSetCapacity(buffer, 4096, 0)
	while DllCall("ReadFile", "Ptr", hReadPipe, "Ptr", &buffer, "UInt", 4096, "UIntP", dwRead, "Ptr", 0)
		sOutput .= StrGet(&buffer, dwRead, Encoding := "UTF-8")

	DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION, 0))         ; hProcess
	DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION, A_PtrSize)) ; hThread
	DllCall("CloseHandle", "Ptr", hReadPipe)
	return sOutput
}